﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using MyWeb.WebUI.Models;
using System.Text;
using WebNext.UI.Properties;
using WebNext.UI.Models;
using System.Threading;
using WebNext.UI.Models.Entries;
using WebNext.Domain.Entities;

namespace WebNext.UI.Utils
{
	public static class HtmlHelpers
	{
		public static MvcHtmlString RenderPageLinks(this HtmlHelper helper, EntriesPagingModel pagingInfo, Func<MainViewType, int, FilterConfig, string> pageUrl)
		{
			StringBuilder result = new StringBuilder();
			if (pagingInfo.TotalPages > 1 && pagingInfo.CurrentPage > 1)
			{
				TagBuilder tag = new TagBuilder("a");
				tag.MergeAttribute("href", pageUrl(pagingInfo.ViewType, pagingInfo.CurrentPage - 1, pagingInfo.FilterConfig));
				tag.MergeAttribute("title",  Properties.Resources.PreviousPage);
				tag.InnerHtml = "<";
				result.AppendLine(tag.ToString());
			}
			for (int i = 1; i <= pagingInfo.TotalPages; i++)
			{
				TagBuilder tag = new TagBuilder("a");
				tag.MergeAttribute("href", pageUrl(pagingInfo.ViewType, i, pagingInfo.FilterConfig));
				tag.InnerHtml = i.ToString();
				if (i == pagingInfo.CurrentPage)
				{
					tag.AddCssClass("selected");
				}
				result.AppendLine(tag.ToString());
			}
			if (pagingInfo.TotalPages > 1 && pagingInfo.CurrentPage < pagingInfo.TotalPages)
			{
				TagBuilder tag = new TagBuilder("a");
				tag.MergeAttribute("href", pageUrl(pagingInfo.ViewType, pagingInfo.CurrentPage + 1, pagingInfo.FilterConfig));
				tag.MergeAttribute("title", Properties.Resources.NextPage);
				tag.InnerHtml = ">";
				result.AppendLine(tag.ToString());
			}
			return MvcHtmlString.Create(result.ToString());
		}
		
		public static MvcHtmlString RenderMessage(this HtmlHelper helper)
		{
			StringBuilder result = new StringBuilder();
			TagBuilder tag = new TagBuilder("div");
			StringBuilder messageBuilder = new StringBuilder();

			if (helper.ViewContext.TempData.ContainsKey(Constants.Message))
			{
				string message = helper.ViewContext.TempData[Constants.Message] as string;
				foreach (string messageLine in message.Split(new string[]{ Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
				{
					messageBuilder.AppendFormat("{0}<br/>", messageLine);
				}
			}
			
			tag.InnerHtml = messageBuilder.ToString();
			tag.AddCssClass("message");
			result.Append(tag.ToString());

			return MvcHtmlString.Create(result.ToString());
		}

		public static MvcHtmlString RenderSiteMenu(this HtmlHelper helper, UrlHelper urlHelper, MainViewModel model)
		{
			StringBuilder result = new StringBuilder();

			TagBuilder blogLink = new TagBuilder("a");
			blogLink.MergeAttribute("title", Resources.MyBlog);
			
			blogLink.MergeAttribute("href", urlHelper.Action("List", "Entries", new { viewType = MainViewType.Blog, pageNumber = 1 }));
			if (model.ViewType == MainViewType.Blog)
			{
			   blogLink.AddCssClass("selected");
			}
			blogLink.SetInnerText(RuntimeSettings.SitePrefix);
			result.AppendLine(blogLink.ToString());

			TagBuilder projectsLink = new TagBuilder("a");
			projectsLink.MergeAttribute("title", Resources.MyProjects);
			projectsLink.MergeAttribute("href", urlHelper.Action("List", "Entries", new { viewType = MainViewType.Projects, pageNumber = 1 }));
			if (model.ViewType == MainViewType.Projects)
			{
			   projectsLink.AddCssClass("selected");
			}
			projectsLink.SetInnerText(Resources.Projects);
			result.AppendLine(projectsLink.ToString());

			TagBuilder contactLink = new TagBuilder("a");
			contactLink.MergeAttribute("title", Resources.ContactAuthor);
			contactLink.MergeAttribute("href", urlHelper.Action("SendMessage", "Contact"));
			if (model.ViewType == MainViewType.Contact)
			{
				contactLink.AddCssClass("selected");
			}
			contactLink.SetInnerText(Resources.Contact);
			result.AppendLine(contactLink.ToString());
	
			if (model.ViewType == MainViewType.Login || model.ViewType == MainViewType.ResetPassword)
			{
				TagBuilder editTagsLink = new TagBuilder("a");
				editTagsLink.MergeAttribute("title", Properties.Resources.LoginToAdminMode);

				editTagsLink.MergeAttribute("href", urlHelper.Action("Login","Login"));
				editTagsLink.AddCssClass("selected");
				editTagsLink.SetInnerText(Properties.Resources.Login);
				result.AppendLine(editTagsLink.ToString());
			}

			if (model.IsLogged)
			{
				TagBuilder editTagsLink = new TagBuilder("a");
				editTagsLink.MergeAttribute("title", Properties.Resources.AddRemoveModifyTags);
				editTagsLink.MergeAttribute("href", urlHelper.Action("Edit", "Tags"));
				if (model.ViewType == MainViewType.EditTags)
				{
					editTagsLink.AddCssClass("selected");
				}
				editTagsLink.SetInnerText(Properties.Resources.EditTags);
				result.AppendLine(editTagsLink.ToString());

				TagBuilder adminLink = new TagBuilder("a");
				adminLink.MergeAttribute("title", Properties.Resources.AdminSettings);
				adminLink.MergeAttribute("href", urlHelper.Action("Edit", "Admin"));
				if (model.ViewType == MainViewType.Admin)
				{
					adminLink.AddCssClass("selected");
				}
				adminLink.SetInnerText(Properties.Resources.Admin);
				result.AppendLine(adminLink.ToString());
			}
			return MvcHtmlString.Create(result.ToString());
		}

		public static MvcHtmlString RenderLoginSwitch(this HtmlHelper helper, UrlHelper urlHelper, bool isLogged)
		{
			if (!isLogged)
			{
				return helper.ActionLink(Resources.Login, "Login", new { controller = "Login" }, new { title = Resources.LoginToAdminMode });
			}
			else
			{
				TagBuilder form = new TagBuilder("form");
				form.Attributes.Add("action",   urlHelper.Action("LogOff", "Login"));
				form.Attributes.Add("method", "post");

				TagBuilder logoffButton = new TagBuilder("button");
				logoffButton.AddCssClass("menuButton");
				logoffButton.InnerHtml = Resources.Logoff;
				logoffButton.Attributes.Add("type", "submit");
				logoffButton.Attributes.Add("title", Resources.LogoffFromAdminMode);

				form.InnerHtml = logoffButton.ToString();

				string formString = form.ToString();
				return MvcHtmlString.Create(formString);
			}
		}

		public static string GetActionName(this HtmlHelper helper)
		{
			return helper.ViewContext.RouteData.Values["action"].ToString();
		}

		public static string GetControllerName(this HtmlHelper helper)
		{
			return helper.ViewContext.RouteData.Values["controller"].ToString();
		}

		public static MvcHtmlString RenderCaptcha(this HtmlHelper helper, bool isValid)
		{
			CaptchaConfiguration captchaConfig = CaptchaHelper.CreateCaptcha(helper.ViewContext.HttpContext);
			
			TagBuilder divCaptcha = new TagBuilder("div");
			divCaptcha.AddCssClass("captcha");
			
			TagBuilder spanA = new TagBuilder("span");
			spanA.AddCssClass("captchaA");
			spanA.InnerHtml = captchaConfig.A.ToString();

			TagBuilder spanB = new TagBuilder("span");
			spanB.AddCssClass("captchaB");
			spanB.InnerHtml = captchaConfig.B.ToString();

			TagBuilder span = new TagBuilder("span");
			span.InnerHtml = string.Format(Resources.CaptchaAdd, spanA.ToString(), spanB.ToString());

			TagBuilder inputCaptchaValue = new TagBuilder("input");
			inputCaptchaValue.Attributes.Add("type", "text");
			inputCaptchaValue.Attributes.Add("maxlength", "2");
			inputCaptchaValue.Attributes.Add("name", "captchaValue");
			if (!isValid)
			{
				inputCaptchaValue.Attributes.Add("class", "errorInput");
			}
			divCaptcha.InnerHtml = span.ToString() + inputCaptchaValue.ToString();

			TagBuilder inputCaptchaKey = new TagBuilder("input");
			inputCaptchaKey.Attributes.Add("type", "hidden");
			inputCaptchaKey.Attributes.Add("name", "captchaKey");
			inputCaptchaKey.Attributes.Add("value", captchaConfig.CaptchaKey);
			divCaptcha.InnerHtml = string.Concat(span, inputCaptchaValue, inputCaptchaKey);
		
			return MvcHtmlString.Create(divCaptcha.ToString());
		}

		public static MvcHtmlString LocalizeJavaScriptVariables(this HtmlHelper helper)
		{
			TagBuilder tag = new TagBuilder("script");
			tag.MergeAttribute("type", "text/javascript");
			StringBuilder scriptBody = new StringBuilder();
			scriptBody.AppendLine("resources = new Object();");
			scriptBody.AppendFormat("resources.UnexpectedAjaxError = \"{0}\";\n", Resources.UnexpectedAjaxError);
			
			tag.InnerHtml = scriptBody.ToString();
			return MvcHtmlString.Create(tag.ToString());
		}

		public static string GetMonthNameByNumber(this HtmlHelper helper, int number)
		{
			return GetMonthNameByNumber(number);
		}

		public static string GetMonthNameByNumber(int number)
		{
			string name = string.Empty;
			switch (number)
			{
				case 1:
					name = Resources.January;
					break;
				case 2:
					name = Resources.February;
					break;
				case 3:
					name = Resources.March;
					break;
				case 4:
					name = Resources.April;
					break;
				case 5:
					name = Resources.May;
					break;
				case 6:
					name = Resources.June;
					break;
				case 7:
					name = Resources.July;
					break;
				case 8:
					name = Resources.August;
					break;
				case 9:
					name = Resources.September;
					break;
				case 10:
					name = Resources.October;
					break;
				case 11:
					name = Resources.November;
					break;
				case 12:
					name = Resources.December;
					break;
				default:
					throw new NotImplementedException("Month numbers must be between 1 - 12");
			}
			return name;
		}
	}
}